﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Windows.Data;

using Microsoft.Practices.Prism.ViewModel;

using Finance.Entites;

namespace Finance.UI.ViewModels
{
    public class PeriodicDetailListViewModel : NotificationObject
    {
        public ObservableCollection<PeriodicDetailGroupViewModel> Groups
        {
            get;
            private set;
        }

        private string _Title;
        public string Title
        {
            get { return _Title; }
            set
            {
                _Title = value;
                RaisePropertyChanged("Title");
            }
        }

        public PeriodicDetailListViewModel(string title, DateTime startdate, DateTime enddate)
        {
            this.Title = title;
            this.Groups = new ObservableCollection<PeriodicDetailGroupViewModel>();
            Action action = () =>
                {
                    this.Groups.Clear();
                    IEnumerable<PeriodicDetailGroupViewModel> fitGroup = App.ChargeDataStore.Items
                        .Where(c => (c.Date > startdate && c.Date < enddate.AddDays(1)))
                        .Select(c => c.Date)
                        .Distinct(new PeriodEqualityComparer())
                        .Select(c => new PeriodicDetailGroupViewModel(c)).ToList();
                    foreach (var item in fitGroup)
                    {
                        this.Groups.Add(item);
                    }
                };
            action();
            //If any changes can affect this group, reset the data source items
            App.ChargeDataStore.Items.CollectionChanged +=
                (o, e) =>
                {
                    switch (e.Action)
                    {
                        case NotifyCollectionChangedAction.Add:
                            {
                                var date = (e.NewItems[0] as Charge).Date;
                                if (Groups.All(c => c.Key != date))
                                {
                                    action();
                                    //Groups.Add(new PeriodicDetailGroupViewModel(date));
                                }
                            }
                            break;
                        case NotifyCollectionChangedAction.Reset:
                            {
                                Groups.Clear();
                            }
                            break;
                        default: break;
                    }
                };
            AddFilter();
        }

        private class PeriodEqualityComparer : IEqualityComparer<DateTime>
        {
            public bool Equals(DateTime x, DateTime y)
            {
                return (x.Year * 10000 + x.Month * 100 + x.Day)
                    == (y.Year * 10000 + y.Month * 100 + y.Day);
            }

            public int GetHashCode(DateTime obj)
            {
                return obj.Year * 10000 + obj.Month * 100 + obj.Day;
            }
        }

        private void AddFilter(string Property = "Key")
        {
            CollectionViewSource sortList = new CollectionViewSource();
            sortList.SortDescriptions.Add(new SortDescription(Property, ListSortDirection.Ascending));
            sortList.Source = this.Groups;
            var tempList = new List<PeriodicDetailGroupViewModel>();
            foreach (var item in sortList.View.Cast<PeriodicDetailGroupViewModel>().ToList())
            {
                tempList.Add(item);
            }
            this.Groups.Clear();
            foreach (var item in tempList)
            {
                this.Groups.Add(item);
            }
        }
    }
}
